package io.github.talelin.latticy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.talelin.latticy.dto.PointsRecordDTO;
import io.github.talelin.latticy.dto.UserRechargeDTO;
import io.github.talelin.latticy.mapper.UserRechargeRecordMapper;
import io.github.talelin.latticy.model.CUserDO;
import io.github.talelin.latticy.model.PointsRecordDO;
import io.github.talelin.latticy.model.UserRechargeRecordDO;
import io.github.talelin.latticy.service.CUserService;
import io.github.talelin.latticy.service.PointsRecordService;
import io.github.talelin.latticy.service.SpuService;
import io.github.talelin.latticy.service.UserRechargeService;
import io.github.talelin.latticy.vo.UserRechargeVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户充值服务实现类
 * @author talelin
 */
@Service
public class UserRechargeServiceImpl extends ServiceImpl<UserRechargeRecordMapper, UserRechargeRecordDO> implements UserRechargeService {

    @Autowired
    private CUserService cUserService;

    @Autowired
    private PointsRecordService pointsRecordService;

    @Autowired
    private SpuService spuService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    @Transactional
    public UserRechargeRecordDO createRechargeRecord(UserRechargeDTO dto) {
        // 创建充值记录
        UserRechargeRecordDO record = new UserRechargeRecordDO();
        BeanUtils.copyProperties(dto, record);
        
        // 计算积分数量（1元=1积分）
        record.setPointsAmount(dto.getRechargeAmount().intValue());
        record.setStatus("pending");
        
        this.save(record);
        return record;
    }

    @Override
    @Transactional
    public UserRechargeRecordDO processRecharge(Integer recordId) {
        UserRechargeRecordDO record = this.getById(recordId);
        if (record == null) {
            throw new RuntimeException("充值记录不存在");
        }
        
        if (!"pending".equals(record.getStatus())) {
            throw new RuntimeException("充值记录状态不正确，无法处理");
        }

        try {
            // 直接使用现有的积分系统创建积分记录
            PointsRecordDTO pointsDto = new PointsRecordDTO();
            pointsDto.setUserId(record.getUserId().longValue());
            pointsDto.setPoints(record.getPointsAmount());
            pointsDto.setTitle("充值获得积分");
            pointsDto.setDescription("充值" + record.getRechargeAmount() + "元获得" + record.getPointsAmount() + "积分");
            pointsDto.setSource("recharge");
            
            PointsRecordDO pointsRecord = pointsRecordService.addPoints(pointsDto);
            
            // 更新充值记录状态
            record.setStatus("success");
            record.setTransactionId(pointsRecord.getId().toString());
            this.updateById(record);
            
            // 自动上架商品
            autoListingByPoints(record.getUserId());
            
            return record;
        } catch (Exception e) {
            // 处理失败
            record.setStatus("failed");
            record.setRemark("处理失败: " + e.getMessage());
            this.updateById(record);
            throw e;
        }
    }

    @Override
    @Transactional
    public UserRechargeRecordDO cancelRecharge(Integer recordId, String reason) {
        UserRechargeRecordDO record = this.getById(recordId);
        if (record == null) {
            throw new RuntimeException("充值记录不存在");
        }
        
        if (!"pending".equals(record.getStatus())) {
            throw new RuntimeException("只有待处理的充值记录才能取消");
        }
        
        record.setStatus("cancelled");
        record.setRemark(reason);
        this.updateById(record);
        
        return record;
    }

    @Override
    public UserRechargeRecordDO getRechargeRecord(Integer recordId) {
        return this.getById(recordId);
    }

    @Override
    public IPage<UserRechargeVO> getUserRechargeRecords(Integer page, Integer count, Integer userId, String status, String rechargeType) {
        Page<UserRechargeRecordDO> pageParam = new Page<>(page, count);
        
        QueryWrapper<UserRechargeRecordDO> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        
        if (status != null && !status.trim().isEmpty()) {
            wrapper.eq("status", status);
        }
        
        if (rechargeType != null && !rechargeType.trim().isEmpty()) {
            wrapper.eq("recharge_type", rechargeType);
        }
        
        wrapper.orderByDesc("create_time");
        
        IPage<UserRechargeRecordDO> records = this.page(pageParam, wrapper);
        
        // 转换为VO
        IPage<UserRechargeVO> result = new Page<>(page, count);
        result.setTotal(records.getTotal());
        result.setCurrent(records.getCurrent());
        result.setSize(records.getSize());
        
        List<UserRechargeVO> voList = records.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        result.setRecords(voList);
        return result;
    }

    @Override
    public IPage<UserRechargeVO> getAllRechargeRecords(Integer page, Integer count, String username, String status, String rechargeType) {
        try {
            // 使用SQL查询优化性能
            return getAllRechargeRecordsBySql(page, count, username, status, rechargeType);
        } catch (Exception e) {
            // 回退到原方法
            return getAllRechargeRecordsFallback(page, count, username, status, rechargeType);
        }
    }

    /**
     * 使用SQL查询所有充值记录（高效版本）
     */
    private IPage<UserRechargeVO> getAllRechargeRecordsBySql(Integer page, Integer count, String username, String status, String rechargeType) {
        // 构建查询SQL
        String sql = buildRechargeRecordsQuery(username, status, rechargeType, count, (page - 1) * count);
        
        // 执行查询
        List<Map<String, Object>> results = jdbcTemplate.queryForList(sql);
        
        // 转换为VO对象
        List<UserRechargeVO> voList = results.stream()
                .map(this::convertMapToVO)
                .collect(Collectors.toList());
        
        // 获取总数
        String countSql = buildRechargeRecordsCountQuery(username, status, rechargeType);
        Long total = jdbcTemplate.queryForObject(countSql, Long.class);
        
        // 创建分页结果
        Page<UserRechargeVO> pageParam = new Page<>(page, count);
        pageParam.setRecords(voList);
        pageParam.setTotal(total != null ? total : 0);
        
        return pageParam;
    }

    /**
     * 构建充值记录查询SQL
     */
    private String buildRechargeRecordsQuery(String username, String status, String rechargeType, Integer limit, Integer offset) {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT ");
        sql.append("    r.id, ");
        sql.append("    r.user_id, ");
        sql.append("    u.nickname as user_nickname, ");
        sql.append("    u.mobile as user_mobile, ");
        sql.append("    r.recharge_amount, ");
        sql.append("    r.points_amount, ");
        sql.append("    r.recharge_type, ");
        sql.append("    r.payment_method, ");
        sql.append("    r.transaction_id, ");
        sql.append("    r.status, ");
        sql.append("    r.operator_id, ");
        sql.append("    r.operator_name, ");
        sql.append("    r.remark, ");
        sql.append("    r.create_time, ");
        sql.append("    r.update_time ");
        sql.append("FROM user_recharge_record r ");
        sql.append("LEFT JOIN user u ON r.user_id = u.id ");
        sql.append("WHERE r.delete_time IS NULL ");
        
        if (username != null && !username.trim().isEmpty()) {
            sql.append("AND (u.nickname LIKE '%").append(username).append("%' OR u.mobile LIKE '%").append(username).append("%') ");
        }
        
        if (status != null && !status.trim().isEmpty()) {
            sql.append("AND r.status = '").append(status).append("' ");
        }
        
        if (rechargeType != null && !rechargeType.trim().isEmpty()) {
            sql.append("AND r.recharge_type = '").append(rechargeType).append("' ");
        }
        
        sql.append("ORDER BY r.create_time DESC ");
        sql.append("LIMIT ").append(limit).append(" OFFSET ").append(offset);
        
        return sql.toString();
    }

    /**
     * 构建充值记录总数查询SQL
     */
    private String buildRechargeRecordsCountQuery(String username, String status, String rechargeType) {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT COUNT(*) ");
        sql.append("FROM user_recharge_record r ");
        sql.append("LEFT JOIN user u ON r.user_id = u.id ");
        sql.append("WHERE r.delete_time IS NULL ");
        
        if (username != null && !username.trim().isEmpty()) {
            sql.append("AND (u.nickname LIKE '%").append(username).append("%' OR u.mobile LIKE '%").append(username).append("%') ");
        }
        
        if (status != null && !status.trim().isEmpty()) {
            sql.append("AND r.status = '").append(status).append("' ");
        }
        
        if (rechargeType != null && !rechargeType.trim().isEmpty()) {
            sql.append("AND r.recharge_type = '").append(rechargeType).append("' ");
        }
        
        return sql.toString();
    }

    /**
     * 回退方法：使用原来的查询方式
     */
    private IPage<UserRechargeVO> getAllRechargeRecordsFallback(Integer page, Integer count, String username, String status, String rechargeType) {
        Page<UserRechargeRecordDO> pageParam = new Page<>(page, count);
        
        QueryWrapper<UserRechargeRecordDO> wrapper = new QueryWrapper<>();
        
        if (status != null && !status.trim().isEmpty()) {
            wrapper.eq("status", status);
        }
        
        if (rechargeType != null && !rechargeType.trim().isEmpty()) {
            wrapper.eq("recharge_type", rechargeType);
        }
        
        wrapper.orderByDesc("create_time");
        
        IPage<UserRechargeRecordDO> records = this.page(pageParam, wrapper);
        
        // 转换为VO
        IPage<UserRechargeVO> result = new Page<>(page, count);
        result.setTotal(records.getTotal());
        result.setCurrent(records.getCurrent());
        result.setSize(records.getSize());
        
        List<UserRechargeVO> voList = records.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        result.setRecords(voList);
        return result;
    }

    @Override
    public List<UserRechargeVO> getUserRechargeStats(Integer userId) {
        // 获取用户充值统计
        String sql = "SELECT " +
                "    COUNT(*) as total_count, " +
                "    SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as success_count, " +
                "    SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_count, " +
                "    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed_count, " +
                "    SUM(CASE WHEN status = 'success' THEN recharge_amount ELSE 0 END) as total_amount, " +
                "    SUM(CASE WHEN status = 'success' THEN points_amount ELSE 0 END) as total_points " +
                "FROM user_recharge_record " +
                "WHERE user_id = ? AND delete_time IS NULL";
        
        List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, userId);
        
        return results.stream()
                .map(this::convertStatsMapToVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public List<UserRechargeRecordDO> batchProcessRecharge(List<Integer> recordIds) {
        List<UserRechargeRecordDO> results = new ArrayList<>();
        
        for (Integer recordId : recordIds) {
            try {
                UserRechargeRecordDO record = processRecharge(recordId);
                results.add(record);
            } catch (Exception e) {
                // 记录失败，继续处理其他记录
                System.err.println("处理充值记录失败: " + recordId + ", 错误: " + e.getMessage());
            }
        }
        
        return results;
    }

    @Override
    @Transactional
    public void autoListingByPoints(Integer userId) {
        // 获取用户当前积分余额
        Integer currentPoints = pointsRecordService.getCurrentBalance(userId.longValue());
        
        if (currentPoints == null || currentPoints <= 0) {
            // 积分不足，下架所有商品
            offlineAllUserProducts(userId);
            System.out.println("用户 " + userId + " 积分不足，已下架所有商品");
            return;
        }
        
        // 使用智能上架策略
        smartListingByPoints(userId, currentPoints);
        
        // 获取最终统计
        int finalOnlineCount = getUserOnlineProductCount(userId);
        System.out.println("用户 " + userId + " 积分调整完成: 当前积分=" + currentPoints + 
                          ", 当前上架=" + finalOnlineCount);
    }
    
    /**
     * 智能上架策略：根据积分余额精确控制上架商品
     */
    private void smartListingByPoints(Integer userId, Integer points) {
        // 获取用户所有商品（按价格排序）
        String sql = "SELECT id, CAST(price AS DECIMAL(10,2)) as price FROM spu " +
                    "WHERE user_id = ? AND delete_time IS NULL " +
                    "ORDER BY CAST(price AS DECIMAL(10,2)) ASC";
        
        List<Map<String, Object>> products = jdbcTemplate.queryForList(sql, userId);
        
        if (products.isEmpty()) {
            System.out.println("用户 " + userId + " 没有商品可上架");
            return;
        }
        
        // 先下架所有商品
        offlineAllUserProducts(userId);
        
        // 根据积分余额智能选择商品上架
        int remainingPoints = points;
        int listedCount = 0;
        
        for (Map<String, Object> product : products) {
            BigDecimal price = (BigDecimal) product.get("price");
            Object idObj = product.get("id");
            Integer productId = null;
            if (idObj instanceof Long) {
                productId = ((Long) idObj).intValue();
            } else if (idObj instanceof Integer) {
                productId = (Integer) idObj;
            } else if (idObj instanceof Number) {
                productId = ((Number) idObj).intValue();
            }
            
            if (productId == null || price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }
            
            // 检查是否有足够积分上架这个商品
            if (remainingPoints >= price.intValue()) {
                // 上架商品
                String updateSql = "UPDATE spu SET online = 1 WHERE id = ?";
                jdbcTemplate.update(updateSql, productId);
                
                remainingPoints -= price.intValue();
                listedCount++;
                
                System.out.println("上架商品 ID=" + productId + ", 价格=" + price + ", 剩余积分=" + remainingPoints);
            } else {
                // 积分不足，停止上架
                break;
            }
        }
        
        System.out.println("用户 " + userId + " 智能上架完成: 上架了 " + listedCount + " 个商品，剩余积分 " + remainingPoints);
    }

    /**
     * 根据积分计算可上架商品数量
     * 商品价格范围：100-1000元，平均每个商品需要500积分
     */
    private int calculateListingCountByPoints(Integer points) {
        if (points == null || points <= 0) {
            return 0;
        }
        
        // 商品价格范围：100-1000元，平均500元
        // 按平均价格计算可上架商品数量
        int averageProductPrice = 500; // 平均商品价格500元
        int maxListingCount = points / averageProductPrice;
        
        // 设置最大上架数量限制
        int maxLimit = 20; // 最多上架20个商品
        return Math.min(maxListingCount, maxLimit);
    }

    /**
     * 转换为VO对象
     */
    private UserRechargeVO convertToVO(UserRechargeRecordDO record) {
        UserRechargeVO vo = new UserRechargeVO();
        BeanUtils.copyProperties(record, vo);
        
        // 设置描述信息
        vo.setRechargeTypeDesc(getRechargeTypeDesc(record.getRechargeType()));
        vo.setPaymentMethodDesc(getPaymentMethodDesc(record.getPaymentMethod()));
        vo.setStatusDesc(getStatusDesc(record.getStatus()));
        
        return vo;
    }

    /**
     * 将Map转换为VO对象
     */
    private UserRechargeVO convertMapToVO(Map<String, Object> row) {
        UserRechargeVO vo = new UserRechargeVO();
        
        vo.setId(getIntegerValue(row.get("id")));
        vo.setUserId(getIntegerValue(row.get("user_id")));
        vo.setUserNickname(getStringValue(row.get("user_nickname")));
        vo.setUserMobile(getStringValue(row.get("user_mobile")));
        vo.setRechargeAmount(getBigDecimalValue(row.get("recharge_amount")));
        vo.setPointsAmount(getIntegerValue(row.get("points_amount")));
        vo.setRechargeType(getStringValue(row.get("recharge_type")));
        vo.setPaymentMethod(getStringValue(row.get("payment_method")));
        vo.setTransactionId(getStringValue(row.get("transaction_id")));
        vo.setStatus(getStringValue(row.get("status")));
        vo.setOperatorId(getIntegerValue(row.get("operator_id")));
        vo.setOperatorName(getStringValue(row.get("operator_name")));
        vo.setRemark(getStringValue(row.get("remark")));
        
        // 设置描述信息
        vo.setRechargeTypeDesc(getRechargeTypeDesc(vo.getRechargeType()));
        vo.setPaymentMethodDesc(getPaymentMethodDesc(vo.getPaymentMethod()));
        vo.setStatusDesc(getStatusDesc(vo.getStatus()));
        
        return vo;
    }

    /**
     * 转换统计Map为VO
     */
    private UserRechargeVO convertStatsMapToVO(Map<String, Object> row) {
        UserRechargeVO vo = new UserRechargeVO();
        // 这里可以根据需要设置统计信息
        return vo;
    }

    // 工具方法
    private String getRechargeTypeDesc(String type) {
        if (type == null) return "";
        switch (type) {
            case "manual": return "手动充值";
            case "auto": return "自动充值";
            case "refund": return "退款";
            default: return type;
        }
    }

    private String getPaymentMethodDesc(String method) {
        if (method == null) return "";
        switch (method) {
            case "alipay": return "支付宝";
            case "wechat": return "微信支付";
            case "bank": return "银行卡";
            case "admin": return "管理员操作";
            default: return method;
        }
    }

    private String getStatusDesc(String status) {
        if (status == null) return "";
        switch (status) {
            case "pending": return "待处理";
            case "success": return "成功";
            case "failed": return "失败";
            case "cancelled": return "已取消";
            default: return status;
        }
    }

    private String getStringValue(Object value) {
        return value != null ? value.toString() : null;
    }

    private Integer getIntegerValue(Object value) {
        if (value == null) return null;
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private BigDecimal getBigDecimalValue(Object value) {
        if (value == null) return null;
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        try {
            return new BigDecimal(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 获取用户当前上架商品数量
     */
    private int getUserOnlineProductCount(Integer userId) {
        String sql = "SELECT COUNT(*) FROM spu WHERE user_id = ? AND online = 1 AND delete_time IS NULL";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class, userId);
        return count != null ? count : 0;
    }

    /**
     * 下架用户所有商品
     */
    private void offlineAllUserProducts(Integer userId) {
        String sql = "UPDATE spu SET online = 0 WHERE user_id = ? AND online = 1 AND delete_time IS NULL";
        int updated = jdbcTemplate.update(sql, userId);
        System.out.println("用户 " + userId + " 下架了 " + updated + " 个商品");
    }

    /**
     * 下架用户指定数量的商品（按价格从高到低，优先下架价格高的商品）
     */
    private void offlineUserProducts(Integer userId, int count) {
        if (count <= 0) return;
        
        // 按价格从高到低排序，优先下架价格高的商品
        String sql = "UPDATE spu SET online = 0 WHERE user_id = ? AND online = 1 AND delete_time IS NULL " +
                    "ORDER BY CAST(price AS DECIMAL(10,2)) DESC LIMIT ?";
        int updated = jdbcTemplate.update(sql, userId, count);
        System.out.println("用户 " + userId + " 下架了 " + updated + " 个商品");
    }

    /**
     * 上架用户指定数量的商品（按价格从低到高，优先上架价格低的商品）
     */
    private void onlineUserProducts(Integer userId, int count) {
        if (count <= 0) return;
        
        // 按价格从低到高排序，优先上架价格低的商品
        String sql = "UPDATE spu SET online = 1 WHERE user_id = ? AND online = 0 AND delete_time IS NULL " +
                    "ORDER BY CAST(price AS DECIMAL(10,2)) ASC LIMIT ?";
        int updated = jdbcTemplate.update(sql, userId, count);
        System.out.println("用户 " + userId + " 上架了 " + updated + " 个商品");
    }

    /**
     * 获取用户商品统计信息
     */
    public Map<String, Object> getUserProductStats(Integer userId) {
        String sql = "SELECT " +
                    "    COUNT(*) as total_products, " +
                    "    SUM(CASE WHEN online = 1 THEN 1 ELSE 0 END) as online_products, " +
                    "    SUM(CASE WHEN online = 0 THEN 1 ELSE 0 END) as offline_products " +
                    "FROM spu " +
                    "WHERE user_id = ? AND delete_time IS NULL";
        
        List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, userId);
        if (results.isEmpty()) {
            Map<String, Object> emptyStats = new HashMap<>();
            emptyStats.put("total_products", 0);
            emptyStats.put("online_products", 0);
            emptyStats.put("offline_products", 0);
            return emptyStats;
        }
        
        return results.get(0);
    }

    /**
     * 批量处理多个用户的自动上架
     */
    @Transactional
    public void batchAutoListingByPoints(List<Integer> userIds) {
        for (Integer userId : userIds) {
            try {
                autoListingByPoints(userId);
            } catch (Exception e) {
                System.err.println("用户 " + userId + " 自动上架处理失败: " + e.getMessage());
            }
        }
    }

    /**
     * 根据积分余额获取上架规则描述
     */
    public String getListingRuleDescription(Integer points) {
        if (points == null || points <= 0) {
            return "积分不足，无法上架商品";
        }
        
        int maxListingCount = calculateListingCountByPoints(points);
        int averageProductPrice = 500;
        
        if (maxListingCount == 0) {
            return "积分不足，无法上架商品（需要至少" + averageProductPrice + "积分）";
        } else if (maxListingCount >= 10) {
            return "积分充足，可上架" + maxListingCount + "个商品（商品价格100-1000元）";
        } else if (maxListingCount >= 5) {
            return "积分良好，可上架" + maxListingCount + "个商品（商品价格100-1000元）";
        } else if (maxListingCount >= 2) {
            return "积分一般，可上架" + maxListingCount + "个商品（商品价格100-1000元）";
        } else {
            return "积分较少，可上架" + maxListingCount + "个商品（商品价格100-1000元）";
        }
    }
}
